using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using Avalonia.Controls;
using Avalonia.Interactivity;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using LiveChartsCore;
using Newtonsoft.Json;
using WeatherCore.App.Models;
using WeatherCore.App.ViewModels.Pages;

namespace WeatherCore.App.Views;

public partial class MainWindow : AppWindow
{
    private Dictionary<string, PageModelBase> Stack { get; }
    private DateTime Now { get; set; } = DateTime.Now;

    private DataWindow Data { get; } = new();

    public MainWindow()
    {
        InitializeComponent();

        Stack = new Dictionary<string, PageModelBase>
        {
            { "Home", new HomeViewModel() },
            { "Weather", new WeatherViewModel() },
            { "Setting", new SettingViewModel() },
            { "Help", new HelpViewModel() }
        };

        TitleBar.ExtendsContentIntoTitleBar = true;
        TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;

        FrameView.IsNavigationStackEnabled = true;
        FrameView.NavigationPageFactory = new NavigationFactory();
        Navigate("Home");

        Data.Closing += (s, e) =>
        {
            ((Window)s!).Hide();
            e.Cancel = true;
        };

        //TaskVisible(new ProgressBar() { IsIndeterminate = true });
    }

    protected override async void OnOpened(EventArgs e)
    {
        base.OnOpened(e);
        var settingModel = SettingModel.Default;

        if (File.Exists("Setting.json"))
            settingModel = JsonConvert.DeserializeObject<SettingModel>(
                await File.ReadAllTextAsync("Setting.json"));
        else
        {
            var stream = File.Create("Setting.json");
            await stream.WriteAsync(Encoding.Default.GetBytes(JsonConvert.SerializeObject(settingModel)));
            await stream.DisposeAsync();
        }

        if (string.IsNullOrEmpty(settingModel?.SaveList.UpdateTime))
            await ((WeatherViewModel)Stack["Weather"]).Change(settingModel?.DefaultCity ?? "北京");
        else
        {
            var w = (WeatherViewModel)Stack["Weather"];
            var date = DateTime.Parse(settingModel.SaveList.UpdateTime);
            if ((DateTime.Now - date).TotalMinutes < 30)
            {
                w.List = settingModel.SaveList.List;
                w.Now = date;
            }
            else
            {
                await ((WeatherViewModel)Stack["Weather"]).Change(settingModel.SaveList.List.CityName);
            }
        }

        ((SettingViewModel)Stack["Setting"]).DefaultCity = settingModel?.DefaultCity ?? "北京";
    }

    protected override void OnClosing(WindowClosingEventArgs e)
    {
        base.OnClosing(e);
        var model = ((SettingViewModel)Stack["Setting"]).GetModel();
        var w = (WeatherViewModel)Stack["Weather"];
        model.SaveList.List = w.List;
        model.SaveList.UpdateTime = w.Now.ToString(CultureInfo.InvariantCulture);
        File.WriteAllText("Setting.json", JsonConvert.SerializeObject(
            model));
    }

    #region Item

    private void ItemInvoked(object? sender, NavigationViewItemInvokedEventArgs e)
    {
        if (e.InvokedItemContainer.Tag is not string s) return;
        if (string.IsNullOrEmpty(s)) return;
        Navigate(s);
    }

    public void Navigate(string page)
    {
        if (string.IsNullOrEmpty(page)) return;
        Navigate(Stack[page]);
    }

    private void Navigate(object context)
    {
        FrameView.NavigateFromObject(context);
        if ((DateTime.Now - Now).TotalMinutes < 2) return;
        FrameView.BackStack.Clear();
        FrameView.ForwardStack.Clear();
        Now = DateTime.Now;
    }

    private void BackClick(object? sender, RoutedEventArgs e)
    {
        FrameView.GoBack();
    }

    #endregion

    public void OpenData(IEnumerable<ISeries> data, string title = "")
    {
        Data.Change(data, title);
        Data.Show();
    }

    public void TaskVisible(Control control)
    {
        TaskItem.Content = control;
    }

    private void PaneClosing(NavigationView sender, NavigationViewPaneClosingEventArgs args)
    {
        if (TaskItem.Content is not Control control) return;
        TaskItem.IconSource = new SymbolIconSource() { Symbol = Symbol.Alert };
        control.IsVisible = false;
    }

    private void PaneOpening(NavigationView sender, EventArgs args)
    {
        if (TaskItem.Content is not Control control) return;
        TaskItem.IconSource = null;
        control.IsVisible = true;
    }
}